package com.cl.short_video_java.web;

import cn.hutool.core.img.Img;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.cl.short_video_java.annotation.Log;
import com.cl.short_video_java.common.Result;
import com.cl.short_video_java.config.FfmpegConfig;
import com.cl.short_video_java.config.TranscodeConfig;
import com.cl.short_video_java.factory.OssFactory;
import com.cl.short_video_java.menum.BusinessType;
import com.cl.short_video_java.util.AliOssUtil;
import com.cl.short_video_java.util.FfmpegUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author 付
 * @Date 2024-03-15 16:41
 * @Version 1.0
 * @description
 * @since 1.0
 */
@Slf4j
@RestController
@RequestMapping("/files")
public class FileController {
	//    文件上传存储路径
	// 也就是根目录下 创建一个file文件夹
	private static final String filePath = System.getProperty("user.dir") + "/file/";
	private static final Logger LOGGER = LoggerFactory.getLogger(FileController.class);
	@Value("${app.video-folder}")
	private String videoFolder;

	private Path tempDir = Paths.get(System.getProperty("java.io.tmpdir"));
	@Autowired
	AliOssUtil aliOssUtil;
	@Autowired
	OssFactory ossFactory;

	//    文件上传
	@PostMapping("/upload")
	@Log(title = "项目图片上传", businessType = BusinessType.INSERT)
	public Result upload(@RequestParam("file") MultipartFile file) throws IOException {
		synchronized (FileController.class) {
			System.out.println("文件路径--" + filePath);
			// 获取一个标志，防止文件重名被覆盖
			String flag = System.currentTimeMillis() + "";
			// 获取文件原名
			String filename = file.getOriginalFilename();
			StringBuilder path = new StringBuilder();

			// 图片压缩
			ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

			Img.from(file.getInputStream())
					.scale(0.6F)// 缩小比例
					.setQuality(0.2) // 压缩比例
					.write(byteArrayOutputStream);
			try {
				// 判断是否存在这个文件夹，如果没有就创建
				if (FileUtil.isDirectory(filePath)) {
					FileUtil.mkdir(filePath);
				}
				// 写文件，将文件写入到指定的文件夹，文件的名称是：flag + 文件原始名称

				FileUtil.writeBytes(byteArrayOutputStream.toByteArray(), filePath + flag + "-" + filename);
				Thread.sleep(1L);
				// 这里就可以将flag存储到数据库中
				// 完整请求路径
				path.append("http://139.159.176.201:8088/image/" + flag + "-" + filename);
				System.out.println("path--" + path);
			} catch (Exception e) {
				System.out.println("存放的文件地址：" + filePath + "---生成的文件名" + filename + "上传失败");
			}
			return Result.success(MapUtil.builder().put("path", path).put("flag", flag + "-" + filename).build());
		}

	}

	@PostMapping("/img")
	@Log(title = "阿里云OSS图片上传", businessType = BusinessType.INSERT)
	public Result img(@RequestParam("file") MultipartFile file) throws IOException {
		String oss = ossFactory.getOss(file);
		return Result.success(oss);
	}

	@PostMapping("/uploadImage")
	public Result uploadImage(@RequestPart(value = "file") MultipartFile file) throws IOException {
		System.out.println("filePath===" + filePath);
		File saveFile = new File(filePath);
		if (!saveFile.exists()) {
			saveFile.mkdir();
		}
		String flag = System.currentTimeMillis() + "";
		String saveName = flag + "-" + file.getOriginalFilename();
		String savePathName = filePath + saveName;
		File result = new File(savePathName);
		file.transferTo(result);
		String viewUrl = "http://139.159.176.201:8088/image/" + saveName;
		return Result.success(MapUtil.builder().put("imageUrl", viewUrl).build());
	}


	//    文件下载
	@GetMapping("/{flag}")
	public Result download(@PathVariable String flag, HttpServletResponse response) {
		System.out.println("+++++++++++++++++++++++++进来了+++++++++++++++++++++++++++++++++++++++");
		if (FileUtil.isDirectory(filePath)) {
			FileUtil.mkdir(filePath);
		}
		OutputStream os;
		// 这里将file下面的所有文件都拿到
		List<String> fileNames = FileUtil.listFileNames(filePath);
		// 循环列表，只要包含了flag，那么就是需要的文件
		String avatar = fileNames.stream().filter(name -> name.contains(flag)).findAny().orElse("");
		String viewUrl = "http://139.159.176.201:8088/image/" + avatar;
		try {
			if (StrUtil.isNotEmpty(avatar)) {
				response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(avatar, "UTF-8"));
				response.setContentType("application/octet-stream");
				byte[] bytes = FileUtil.readBytes(filePath + avatar);
				os = response.getOutputStream();
				os.write(bytes);
				os.flush();
				os.close();
			}
		} catch (Exception e) {
			System.out.println("文件下载失败");
		}

		return Result.success(viewUrl);
	}

	//删除图片文件，只是删除文件，不删除数据库信息
	@PostMapping("/{flag}")
	@ResponseBody
	public Result delFile(@PathVariable String flag) {
		if (FileUtil.isDirectory(filePath)) {
			FileUtil.mkdir(filePath);
		}

		System.out.println(flag);
		String[] newflag = flag.split("-");
		String resultInfo = "";
		// 这里将file下面的所有文件都拿到
		List<String> fileNames = FileUtil.listFileNames(filePath);
		System.out.println(fileNames);
		String avatar = fileNames.stream().filter(name -> name.contains(newflag[0])).findAny().orElse("");

		System.out.println("获取的数据---》" + avatar);
		File file = new File(avatar);
		System.out.println("file--->" + file + "--" + file.exists());
		if (file.exists()) {//文件是否存在
			System.out.println("存在");
			if (file.delete()) {//存在就删了，返回1
				resultInfo = "1";
			} else {
				resultInfo = "0";
			}
		} else {
			resultInfo = "文件不存在！";
		}
		return Result.success("删除成功");
	}


	@PostMapping("/uploadToM3u8")
	public void uploadToM3u8() throws Exception {
		// 模拟一个已被服务器保存的MP4文件
		FileInputStream inputStream = new FileInputStream("E:\\Code\\JavaLearn\\SpringBootTest\\springboot-video\\src\\test\\resources\\Video\\testVideo.mp4");
		FfmpegUtil.changeMediaToM3u8(inputStream);// 进行切片保存
	}


	//    @CrossOrigin(origins = "http://localhost)
	@GetMapping("/play/{file:.+}")
	public Result play(@PathVariable String file) {
		Path videoPath = Paths.get(FfmpegConfig.VIDEOS_FOLDER, file);
		try {
			// 检查文件是否存在且可读
			Resource resource = new UrlResource(videoPath.toUri());
			if (resource.exists() || resource.isReadable()) {
				// 设置Content-Disposition头部，非必须
				HttpHeaders headers = new HttpHeaders();
				headers.add(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + resource.getFilename() + "\"");

				// 根据文件扩展名设置Content-Type头部，非必须
				if (videoPath.toString().endsWith(".m3u8")) {
					headers.setContentType(MediaType.parseMediaType("application/vnd.apple.mpegurl"));
				} else if (videoPath.toString().endsWith(".ts")) {
					headers.setContentType(MediaType.parseMediaType("video/mp2t"));
				}

				// 返回文件资源
//				return ResponseEntity.ok().headers(headers).body(resource);
				return Result.success(resource);
			} else {
				log.error("文件不可读或不存在: {}", videoPath);
				return Result.error("文件不可读或不存在");
			}
		} catch (Exception e) {
			log.error("错误: {}", videoPath, e);
			return Result.error(e.getMessage());
		}
	}
}

